package com.softWang.system.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.softWang.common.base.BaseServiceMy;
import com.softWang.common.exception.LogicException;
import com.softWang.system.controller.vo.systemDepts.SystemDeptQueryAllParam;
import com.softWang.system.controller.vo.systemDepts.SystemDeptQueryAllResult;
import com.softWang.system.mapper.SystemDeptsMapper;
import com.softWang.system.mapper.SystemUsersMapper;
import com.softWang.system.po.SystemDepts;
import com.softWang.system.po.SystemUsers;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

@Service
public class SystemDeptsService extends BaseServiceMy<SystemUsers> {
    @Resource
    private SystemDeptsMapper systemDeptsMapper;
    @Resource
    private SystemUsersMapper systemUsersMapper;

    /**
     * 分页条件查询
     * @param param
     * @return
     */
    public List<SystemDeptQueryAllResult> queryall(SystemDeptQueryAllParam param){
        param.startPage();
        List<SystemDeptQueryAllResult> users=systemDeptsMapper.queryall(param);
        return users;
    }

    /**
     * 插入部门
     * @param dept 部门信息
     * @return 部门id
     */
    @Transactional
    public Long add(SystemDepts dept) {
        if(dept.getPid() == null){ dept.setPid(0L); }
        // 验证部门名称再同一个父级下的唯一性
        Long num = systemDeptsMapper.selectCount(
                new LambdaQueryWrapper<SystemDepts>()
                        .eq(SystemDepts::getDname, dept.getDname())
                        .eq(SystemDepts::getPid, dept.getPid()));
        if (num > 0) {
            throw new LogicException("部门名称已存在!");
        }
        // 设置部门信息
        dept.setType(SystemDepts.Type.CREATED.getCode());
        dept.setState(SystemDepts.State.NORMAL.getCode());

        systemDeptsMapper.insert(dept);

        //更新treecode
        String treecode = dept.getPid() == 0 ? dept.getId().toString() + "," : systemDeptsMapper.selectById(dept.getPid()).getTreecode() + dept.getId() + ",";
        dept.setTreecode(treecode);

        systemDeptsMapper.updateById(dept);

        return dept.getId();
    }



    /**
     * 修改部门
     * @param dept     *
     * @return
     */
    @Transactional
    public Long edit(SystemDepts dept) {
        //先判断是否内置部门，内置部门不可修改
        SystemDepts old = systemDeptsMapper.selectById(dept.getId());
        if(old == null){
            throw new LogicException("部门不存在");
        }
        if(old.getType() == SystemDepts.Type.INNER.getCode()){
            throw new LogicException("内置部门，不可修改");
        }
        if(dept.getPid() == null){ dept.setPid(0L); }
        // 验证部门名称再同一个父级下的唯一性
        Long num = systemDeptsMapper.selectCount(
                new LambdaQueryWrapper<SystemDepts>()
                        .eq(SystemDepts::getDname, dept.getDname())
                        .eq(SystemDepts::getPid, dept.getPid())
                        .ne(SystemDepts::getId, dept.getId()));
        if (num > 0) {
            throw new LogicException("部门名称已存在!");
        }
        // 设置部门信息
        dept.setType(SystemDepts.Type.CREATED.getCode());
        dept.setState(SystemDepts.State.NORMAL.getCode());
        dept.setTreecode(old.getTreecode());
        // 修改部门信息
        systemDeptsMapper.updateById(dept);

        // 判断上级部门是否修改，修改后需要更新treecode
        if(dept.getPid() != old.getPid()){
            // 验证上级部门是否存在
            SystemDepts parent = systemDeptsMapper.selectById(dept.getPid());
            if(parent == null){
                throw new LogicException("上级部门不存在");
            }
            // 不能选择自己或自己的子部门作为上级部门
            if(parent.getId() == dept.getId() || parent.getTreecode().contains(old.getTreecode())){
                throw new LogicException("不能选择自己或自己的子部门作为上级部门");
            }
            String selfTreecodeNew = dept.getPid() == 0 ? dept.getId().toString() + "," : parent.getTreecode() + dept.getId() + ",";

            // 更新自己及子部门的treecode
            List<SystemDepts> selfAndChildren =systemDeptsMapper.selectList(
                    Wrappers.lambdaQuery(SystemDepts.class)
                            .likeRight(SystemDepts::getTreecode, old.getTreecode()));
            selfAndChildren.forEach(d -> {
                        String treeCodeOld = d.getTreecode();
                        String treeCodeNew = selfTreecodeNew + treeCodeOld.substring(old.getTreecode().length(), treeCodeOld.length());
                        d.setTreecode(treeCodeNew);
                    });

            systemDeptsMapper.updateById(selfAndChildren);
        }

        return dept.getId();
    }


    /**
     * 删除部门
     * @param ids 部门id列表
     * @return void
     */
    @Transactional
    public void del(List<Long> ids) {
        //部门下有子部门不能删除
        Long childNum = systemDeptsMapper.selectCount(Wrappers.lambdaQuery(SystemDepts.class)
                .in(SystemDepts::getPid,ids));
        if(childNum > 0){
            throw new LogicException("该部门下有子部门，不能删除");
        }
        //部门下有用户不能删除
        Long userNum = systemUsersMapper.selectCount(Wrappers.lambdaQuery(SystemUsers.class)
                .in(SystemUsers::getDeptid,ids));
        if(userNum > 0){
            throw new LogicException("该部门下有用户，不能删除");
        }
        //删除部门
        systemDeptsMapper.deleteBatchIds(ids);
    }
    /**
     * 获取机构树列表
     * @param deptId 异步加载时需要传上级部门id
     * @return 机构树列表
     */
    public List<SystemDepts> getOrgTree(Long deptId) {
        List<SystemDepts> depts = systemDeptsMapper.selectList(Wrappers.lambdaQuery(SystemDepts.class)
                .eq(deptId!=null,SystemDepts::getPid, deptId)
                .eq(SystemDepts::getState, SystemDepts.State.NORMAL.getCode()));
        return depts;
    }

    /**
     * 获取部门信息
     * @param deptId 部门id
     * @return 部门信息
     */
    public SystemDepts getById(Long deptId) {
        return systemDeptsMapper.selectById(deptId);
    }
}
